﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.ComponentModel;
using FinPlusCommon;
using log = Logger.Logger;

namespace FinPlusComponents
{
    public class QLParseDepoTrade : FinPlusComponent
    {
        private enum Params { ParseTradeAction, ResponseAction, BuySell, QuoteAccept, DepoLoan, QuoteRef, PayRec, Instrument, Settle, End, Size, Quote, Book, Counterparty, MarketName, CacheName, TempId, CurveName, Nominal, Rate, Start, Maturity, Index }
        private readonly IFinPlusComp _instrumentBuildConn, _tradeAdaptorConn;
        private readonly FinPlusConnectDB _tradeSaveConn;
        private readonly IFunction _tradeAdaptor;

        //construct
        public QLParseDepoTrade(IFinPlusComp instrumentBuilds, IFinPlusComp tradeAdaptors, IFinPlusComp tradeSave) 
        {
            _instrumentBuildConn = instrumentBuilds;
            _tradeAdaptorConn = tradeAdaptors;
            _tradeSaveConn = (FinPlusConnectDB)tradeSave; 
            _tradeAdaptor = _tradeAdaptorConn.Adaptor.First("Name='InstrumentType' And Value='Depo'");
            _tradeAdaptor.Get(Params.ParseTradeAction.ToString(), Parse_Trade);
            IsValid = true;
        }

        //common control interface
        public override void Dispose()
        {
            try
            {
                if (_tradeSaveConn != null)
                    _tradeSaveConn.Dispose();
                if (_instrumentBuildConn != null)
                    _instrumentBuildConn.Dispose();
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Warning, Id, Config, e.Message, e);
            }
        }

        public override void CmdExecute(IFunction command)
        {
            try
            {
                CmdCapture(command);

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.QuoteAccept: ExecutionParse(command); break;
                    case Cmds.QuoteAcceptPublish: ExecutionParse(command); break;
                    default: throw new FormatException(string.Format("event not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
                IsValid = log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        //private
        private bool ExecutionParse(IFunction func)
        {
            try
            {
                //trade parse
                var instrument = func[Params.Instrument.ToString()].ToString();
                var instrumentBuild = _instrumentBuildConn.Adaptor.First("Name='Instrument' And Value='" + instrument + "'");

                var trade = new Function(Params.DepoLoan.ToString());
                trade.Add(Params.Book.ToString(), func[Params.Book.ToString()].ToString());
                trade.Add(Params.Counterparty.ToString(), func[Params.Counterparty.ToString()].ToString());
                trade.Add(Params.MarketName.ToString(), string.Empty);
                trade.Add(Params.CacheName.ToString(), string.Empty);
                trade.Add(Params.TempId.ToString(), func[Params.QuoteRef.ToString()].ToString());
                trade.Add(Params.CurveName.ToString(), instrumentBuild[Params.CurveName.ToString()].ToString());
                trade.Add(Params.Nominal.ToString(), (double)func.Value(Params.Size.ToString()));
                trade.Add(Params.Rate.ToString(), (double)func.Value(Params.Quote.ToString()));

                if (func.Name.Equals(Params.QuoteAccept.ToString()))
                    trade.Add(Params.PayRec.ToString(), func[Params.BuySell.ToString()].Equals("Buy") ? "Receiver" : "Payer");
                else
                    trade.Add(Params.PayRec.ToString(), func[Params.BuySell.ToString()].Equals("Buy") ? "Payer" : "Receiver");
                
                trade.Add(Params.Start.ToString(), (DateTime)func.Value(Params.Settle.ToString()));
                trade.Add(Params.Maturity.ToString(), (DateTime)func.Value(Params.End.ToString()));
                trade.Add(Params.Index.ToString(), instrumentBuild[Params.Index.ToString()].ToString());

                //save trade
                _tradeSaveConn.Save(trade);

                //respond with trade for testing
                trade.Add(Params.Instrument.ToString(), instrument);
                _tradeAdaptor.Get(Params.ResponseAction.ToString()).Set(trade);

                return true;
            }
            catch (Exception e)
            {
                return IsValid = log.Log(Logger.Level.Error, func.ToString(), e);
            }
        }

        //cmds
        private enum Cmds { QuoteAccept, QuoteAcceptPublish };

        //events
        private void Parse_Trade(object s, PropertyChangedEventArgs a) { CmdRouter(s); }//QuoteAccept && QuotePublishAccept
    }
}
